package servlet;

import anno.Autowired;
import anno.RequestBody;
import anno.ResponseBody;
import com.fasterxml.jackson.core.JsonProcessingException;
import dao.ExamPaperDao;
import dao.ExamRecordDao;
import pojo.ExamPaper;
import pojo.ExamRecord;
import utils.ApiResult;
import utils.JsonUtils;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.*;

@WebServlet("/exam")
public class ExamRecordServlet extends BaseServlet {

    @Autowired
    private ExamRecordDao recordDao;

    @Autowired
    private ExamPaperDao paperDao;

    @ResponseBody
    public ApiResult startExam(HttpServletRequest req, HttpServletResponse resp, String paperId, String userId) throws SQLException, JsonProcessingException {
        if (userId == null || paperId == null) {
            return new ApiResult(400, "缺少必要参数", null);
        }

        // 检查试卷是否存在且启用
        ExamPaper paper = paperDao.findById(Integer.valueOf(paperId));
        if (paper == null || paper.getStatus() == 0) {
            return new ApiResult(404, "试卷不存在或已禁用", null);
        }

        // 检查是否已经参加过考试
        ExamRecord existingRecord = recordDao.findByUserIdAndPaperId(Integer.valueOf(userId), Integer.valueOf(paperId));
        if (existingRecord != null) {
            return new ApiResult(409, "您已参加过此考试", null); // 返回409状态码，数据为null
        }

        // 创建考试记录
        ExamRecord record = new ExamRecord();
        record.setUserId(Integer.valueOf(userId));
        record.setPaperId(Integer.valueOf(paperId));
        record.setStartTime(LocalDateTime.now());
        recordDao.insert(record);

        // 返回试卷信息（包含题目列表）
        paper = paperDao.findById(Integer.valueOf(paperId));
        return new ApiResult(200, "开始考试", paper);
    }

    @ResponseBody
    public ApiResult getExamRecords(HttpServletRequest req, HttpServletResponse resp, String userId) throws SQLException {
        if (userId == null) {
            return new ApiResult(400, "缺少必要参数", null);
        }
        List<ExamRecord> records = recordDao.findByUserId(Integer.valueOf(userId));
        return new ApiResult(200, "获取考试记录成功", records);
    }

    @ResponseBody
    public ApiResult getExamDetail(HttpServletRequest req, HttpServletResponse resp, String recordId) throws SQLException, JsonProcessingException {
        if (recordId == null) {
            return new ApiResult(400, "缺少必要参数", null);
        }
        ExamRecord record = recordDao.findById(Integer.valueOf(recordId));
        if (record == null) {
            return new ApiResult(404, "未找到考试记录", null);
        }
        ExamPaper paper = paperDao.findById(record.getPaperId());
        if (paper == null) {
            return new ApiResult(404, "试卷不存在", null);
        }
        Map<String, Object> data = new HashMap<>();
        data.put("paper", paper);

        if (record.getEndTime() != null) {
            // 考试已结束
            if (record.getAnswers() != null) {
                // 学生已提交考试，解析答案
                Map<String, String> answers = JsonUtils.parseJsonToMap(record.getAnswers());
                data.put("answers", answers);
                data.put("status", "submitted"); // 表示已提交
            } else {
                // 考试已结束但未提交答案，可能是异常情况
                data.put("answers", new HashMap<String, String>());
                data.put("status", "submitted");
                data.put("score", 0);
                // 更新考试记录得分为0
                record.setScore(0);
                recordDao.update(record);
            }
        } else {
            // 考试未结束
            data.put("answers", new HashMap<String, String>());
            data.put("status", "in_progress"); // 表示考试进行中
        }

        return new ApiResult(200, "获取考试详情成功", data);
    }

    @ResponseBody
    public ApiResult submitExam(HttpServletRequest req, HttpServletResponse resp, @RequestBody Map<String, Object> requestData) throws SQLException, JsonProcessingException {
        Integer userId = (Integer) requestData.get("userId");
        Integer paperId = (Integer) requestData.get("paperId");
        Map<String, String> answers = (Map<String, String>) requestData.get("answers");

        if (userId == null || paperId == null || answers == null) {
            return new ApiResult(400, "缺少必要参数", null);
        }

        ExamRecord record = recordDao.findByUserIdAndPaperId(userId, paperId);
        if (record == null) {
            return new ApiResult(404, "未找到考试记录，请先开始考试", null);
        }

        if (record.getEndTime() != null) {
            return new ApiResult(400, "您已提交过考试", null);
        }

        // 获取试卷信息
        ExamPaper paper = paperDao.findById(paperId);
        if (paper == null) {
            return new ApiResult(404, "试卷不存在", null);
        }

        // 计算得分
        int score = calculateScore(paper, answers);

        // 更新考试记录
        record.setEndTime(LocalDateTime.now());
        record.setAnswers(JsonUtils.toJson(answers));
        record.setScore(score);
        recordDao.update(record);

        Map<String, Object> resultData = new HashMap<>();
        resultData.put("score", score);
        resultData.put("passScore", paper.getPassScore());

        return new ApiResult(200, "考试提交成功", resultData);
    }

    /**
     * 计算得分
     */
    private int calculateScore(ExamPaper paper, Map<String, String> answers) throws SQLException, JsonProcessingException {
        int totalScore = 0;

        // 获取试卷中的题目ID列表
        List<String> questionIds = JsonUtils.parseJsonToList(paper.getQuestions());

        // 获取题目的正确答案
        Map<Integer, String> correctAnswers = paperDao.getCorrectAnswersByQuestionIds(questionIds);

        // 逐题比较答案
        for (String qIdStr : questionIds) {
            Integer qId = Integer.valueOf(qIdStr.trim());
            String correctAnswer = correctAnswers.get(qId);
            String userAnswer = answers.get(qIdStr);

            if (correctAnswer != null && correctAnswer.equalsIgnoreCase(userAnswer)) {
                // 答对，累加分数
                totalScore += paperDao.getQuestionScoreById(qId);
            }
        }

        return totalScore;
    }
}
